import os
import sys
import re
import tkinter as tk
from tkinter import ttk, messagebox, filedialog
import win32print
import subprocess
import threading
import ctypes
import win32com.shell.shell as shell
import datetime

def is_admin():
    """检查当前程序是否以管理员权限运行"""
    try:
        return ctypes.windll.shell32.IsUserAnAdmin()
    except:
        return False

class PrinterInstaller:
    def __init__(self, root):
        self.root = root
        self.root.title("网络打印机安装向导")
        self.root.geometry("700x500")
        self.root.resizable(False, False)
        self.root.iconbitmap(default=None)
        
        # 设置中文字体支持
        self.style = ttk.Style()
        self.style.configure(
            "TLabel", 
            font=('Microsoft YaHei UI', 10),
            padding=5
        )
        self.style.configure(
            "TButton", 
            font=('Microsoft YaHei UI', 10),
            padding=5
        )
        self.style.configure(
            "TEntry", 
            font=('Microsoft YaHei UI', 10),
            padding=5
        )
        
        # 创建步骤框架
        self.steps_frame = ttk.Frame(root)
        self.steps_frame.pack(fill=tk.X, padx=20, pady=10)
        
        # 创建内容框架
        self.content_frame = ttk.Frame(root)
        self.content_frame.pack(fill=tk.BOTH, expand=True, padx=20, pady=10)
        
        # 创建按钮框架
        self.button_frame = ttk.Frame(root)
        self.button_frame.pack(fill=tk.X, padx=20, pady=10)
        
        # 当前步骤
        self.current_step = 1
        self.total_steps = 4
        
        # 创建步骤指示器
        self.create_step_indicator()
        
        # 存储用户输入
        self.printer_ip = tk.StringVar(value="192.168.30.199")
        self.printer_name = tk.StringVar(value="Km-print")
        self.driver_path = tk.StringVar(value="\\\\192.168.30.200\\km\\soft\\驱动\\HP3104\\hp3104")
        self.selected_inf = tk.StringVar()
        self.inf_files = []
        
        # 先创建按钮
        self.create_buttons()
        
        # 显示第一步（这会自动调用update_buttons）
        self.show_step(self.current_step)
    
    def create_step_indicator(self):
        self.steps = []
        for i in range(1, self.total_steps + 1):
            step_frame = ttk.Frame(self.steps_frame)
            step_frame.pack(side=tk.LEFT, fill=tk.BOTH, expand=True)
            
            # 步骤圆圈
            canvas = tk.Canvas(step_frame, width=30, height=30, highlightthickness=0)
            canvas.pack(pady=5)
            
            # 初始状态：只有第一步是活动状态
            if i == 1:
                canvas.create_oval(5, 5, 25, 25, fill="#4CAF50", outline="")
                canvas.create_text(15, 15, text=str(i), fill="white", font=('Microsoft YaHei UI', 10, 'bold'))
            else:
                canvas.create_oval(5, 5, 25, 25, fill="#E0E0E0", outline="")
                canvas.create_text(15, 15, text=str(i), fill="#757575", font=('Microsoft YaHei UI', 10))
            
            # 步骤文本
            text = self.get_step_text(i)
            label = ttk.Label(step_frame, text=text)
            label.pack()
            
            self.steps.append((canvas, label))
    
    def get_step_text(self, step):
        texts = [
            "输入打印机IP",
            "输入打印机名称",
            "选择驱动文件夹路径",
            "选择驱动文件"
        ]
        return texts[step-1] if 1 <= step <= len(texts) else ""
    
    def update_step_indicator(self):
        for i in range(self.total_steps):
            canvas, label = self.steps[i]
            canvas.delete("all")
            
            if i + 1 < self.current_step:
                # 已完成的步骤
                canvas.create_oval(5, 5, 25, 25, fill="#4CAF50", outline="")
                canvas.create_text(15, 15, text="✓", fill="white", font=('Microsoft YaHei UI', 10, 'bold'))
                label.config(foreground="#4CAF50")
            elif i + 1 == self.current_step:
                # 当前步骤
                canvas.create_oval(5, 5, 25, 25, fill="#4CAF50", outline="")
                canvas.create_text(15, 15, text=str(i + 1), fill="white", font=('Microsoft YaHei UI', 10, 'bold'))
                label.config(foreground="#4CAF50")
            else:
                # 未完成的步骤
                canvas.create_oval(5, 5, 25, 25, fill="#E0E0E0", outline="")
                canvas.create_text(15, 15, text=str(i + 1), fill="#757575", font=('Microsoft YaHei UI', 10))
                label.config(foreground="#757575")
    
    def show_step(self, step):
        # 清空内容框架
        for widget in self.content_frame.winfo_children():
            widget.destroy()
        
        if step == 1:
            self.show_step_1()
        elif step == 2:
            self.show_step_2()
        elif step == 3:
            self.show_step_3()
        elif step == 4:
            self.show_step_4()
        
        self.update_step_indicator()
        self.update_buttons()  # 更新按钮状态
    
    def show_step_1(self):
        header = ttk.Label(self.content_frame, text="输入打印机IP地址", font=('Microsoft YaHei UI', 12, 'bold'))
        header.pack(anchor=tk.W, pady=10)
        
        ip_frame = ttk.Frame(self.content_frame)
        ip_frame.pack(fill=tk.X, pady=10)
        
        ip_label = ttk.Label(ip_frame, text="打印机IP地址:", width=15)
        ip_label.pack(side=tk.LEFT, padx=5)
        
        ip_entry = ttk.Entry(ip_frame, textvariable=self.printer_ip, width=30)
        ip_entry.pack(side=tk.LEFT, fill=tk.X, expand=True, padx=5)
        
        default_info = ttk.Label(self.content_frame, text="默认IP地址: 192.168.30.199", foreground="#757575")
        default_info.pack(anchor=tk.W, pady=5)
        
        check_button = ttk.Button(self.content_frame, text="检查并删除现有打印机", command=self.check_and_remove_printer)
        check_button.pack(anchor=tk.W, pady=10)
    
    def show_step_2(self):
        header = ttk.Label(self.content_frame, text="输入打印机名称", font=('Microsoft YaHei UI', 12, 'bold'))
        header.pack(anchor=tk.W, pady=10)
        
        name_frame = ttk.Frame(self.content_frame)
        name_frame.pack(fill=tk.X, pady=10)
        
        name_label = ttk.Label(name_frame, text="打印机名称:", width=15)
        name_label.pack(side=tk.LEFT, padx=5)
        
        name_entry = ttk.Entry(name_frame, textvariable=self.printer_name, width=30)
        name_entry.pack(side=tk.LEFT, fill=tk.X, expand=True, padx=5)
        
        default_info = ttk.Label(self.content_frame, text="默认打印机名称: Km-print", foreground="#757575")
        default_info.pack(anchor=tk.W, pady=5)
    
    def show_step_3(self):
        header = ttk.Label(self.content_frame, text="选择驱动文件夹路径", font=('Microsoft YaHei UI', 12, 'bold'))
        header.pack(anchor=tk.W, pady=10)
        
        path_frame = ttk.Frame(self.content_frame)
        path_frame.pack(fill=tk.X, pady=10)
        
        path_label = ttk.Label(path_frame, text="驱动路径:", width=15)
        path_label.pack(side=tk.LEFT, padx=5)
        
        path_entry = ttk.Entry(path_frame, textvariable=self.driver_path, width=30)
        path_entry.pack(side=tk.LEFT, fill=tk.X, expand=True, padx=5)
        
        browse_button = ttk.Button(path_frame, text="浏览...", command=self.browse_driver_path)
        browse_button.pack(side=tk.RIGHT, padx=5)
        
        default_info = ttk.Label(self.content_frame, text="默认驱动路径: \\192.168.30.200\\km\\soft\\驱动\\HP3104\\hp3104", foreground="#757575")
        default_info.pack(anchor=tk.W, pady=5)
        
        # 提示信息
        info_label = ttk.Label(
            self.content_frame, 
            text="请确保您有权限访问该网络共享路径", 
            foreground="#FF9800"
        )
        info_label.pack(anchor=tk.W, pady=5)
    
    def show_step_4(self):
        header = ttk.Label(self.content_frame, text="选择打印机驱动文件", font=('Microsoft YaHei UI', 12, 'bold'))
        header.pack(anchor=tk.W, pady=10)
        
        # 首先尝试加载INF文件
        self.load_inf_files()
        
        if self.inf_files:
            # 创建滚动框架
            scroll_frame = ttk.Frame(self.content_frame)
            scroll_frame.pack(fill=tk.BOTH, expand=True, pady=10)
            
            # 创建滚动条
            scrollbar = ttk.Scrollbar(scroll_frame)
            scrollbar.pack(side=tk.RIGHT, fill=tk.Y)
            
            # 创建列表框
            self.inf_listbox = tk.Listbox(
                scroll_frame,
                yscrollcommand=scrollbar.set,
                font=('Microsoft YaHei UI', 10),
                selectmode=tk.SINGLE,
                width=70,
                height=10
            )
            self.inf_listbox.pack(side=tk.LEFT, fill=tk.BOTH, expand=True)
            scrollbar.config(command=self.inf_listbox.yview)
            
            # 添加INF文件到列表框
            for inf_file in self.inf_files:
                self.inf_listbox.insert(tk.END, inf_file)
            
            # 默认选择第一个
            if self.inf_files:
                self.inf_listbox.select_set(0)
                self.selected_inf.set(self.inf_files[0])
            
            # 绑定选择事件
            self.inf_listbox.bind('<<ListboxSelect>>', self.on_inf_select)
            
            # 按钮由update_buttons方法统一管理
        else:
            error_label = ttk.Label(
                self.content_frame, 
                text="无法在指定路径找到INF驱动文件，请检查路径是否正确", 
                foreground="#F44336"
            )
            error_label.pack(pady=20)
            
            retry_button = ttk.Button(self.content_frame, text="重新选择路径", command=lambda: self.show_step(3))
            retry_button.pack(pady=10)
    
    def create_buttons(self):
        # 左对齐的上一步按钮
        self.prev_button = ttk.Button(self.button_frame, text="上一步", command=self.prev_step)
        self.prev_button.pack(side=tk.LEFT, padx=5)
        
        # 右对齐的下一步和完成按钮
        button_container = ttk.Frame(self.button_frame)
        button_container.pack(side=tk.RIGHT)
        
        self.next_button = ttk.Button(button_container, text="下一步", command=self.next_step)
        self.next_button.pack(side=tk.LEFT, padx=5)
        
        self.finish_button = ttk.Button(button_container, text="完成", command=self.finish)
        self.finish_button.pack(side=tk.LEFT, padx=5)
        self.finish_button.pack_forget()  # 初始隐藏完成按钮
    
    def update_buttons(self):
        # 更新上一步按钮状态
        if self.current_step == 1:
            self.prev_button.config(state=tk.DISABLED)
        else:
            self.prev_button.config(state=tk.NORMAL)
        
        # 更新下一步和完成按钮
        if self.current_step == self.total_steps:
            self.next_button.pack_forget()
            # 在第4步时，将finish_button的命令设置为install_printer
            self.finish_button.config(text="安装打印机", command=self.install_printer)
            self.finish_button.pack(side=tk.LEFT, padx=5)
        else:
            self.finish_button.pack_forget()
            self.next_button.pack(side=tk.LEFT, padx=5)
    
    def prev_step(self):
        if self.current_step > 1:
            self.current_step -= 1
            self.show_step(self.current_step)
            self.update_buttons()
    
    def next_step(self):
        # 验证当前步骤
        if not self.validate_current_step():
            return
        
        if self.current_step < self.total_steps:
            self.current_step += 1
            self.show_step(self.current_step)
            self.update_buttons()
    
    def finish(self):
        # 验证当前步骤
        if not self.validate_current_step():
            return
        
        # 安装打印机
        self.install_printer()
    
    def validate_current_step(self):
        if self.current_step == 1:
            # 验证IP地址格式
            ip = self.printer_ip.get().strip()
            if not self.is_valid_ip(ip):
                messagebox.showerror("错误", "请输入有效的IP地址")
                return False
        elif self.current_step == 2:
            # 验证打印机名称
            name = self.printer_name.get().strip()
            if not name:
                messagebox.showerror("错误", "打印机名称不能为空")
                return False
        elif self.current_step == 3:
            # 验证驱动路径
            path = self.driver_path.get().strip()
            if not os.path.isdir(path):
                # 尝试使用UNC路径格式
                if path.startswith("\\"):
                    # 对于网络路径，我们只检查格式是否正确
                    if not re.match(r'^\\\\[^\\]+\\[^\\]+.*$', path):
                        messagebox.showerror("错误", "请输入有效的网络共享路径")
                        return False
                else:
                    messagebox.showerror("错误", "找不到指定的驱动文件夹")
                    return False
        elif self.current_step == 4:
            # 验证是否选择了INF文件
            if not self.selected_inf.get():
                messagebox.showerror("错误", "请选择一个驱动文件")
                return False
        
        return True
    
    def is_valid_ip(self, ip):
        # 简单的IP地址格式验证
        pattern = r'^((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$'
        return re.match(pattern, ip) is not None
    
    def check_and_remove_printer(self):
        # 检查管理员权限
        if not is_admin():
            result = messagebox.askyesno(
                "需要管理员权限", 
                "删除打印机需要管理员权限。\n\n是否以管理员权限重新启动程序？"
            )
            if result:
                # 以管理员权限重新启动程序
                try:
                    script_path = os.path.abspath(__file__)
                    ctypes.windll.shell32.ShellExecuteW(
                        None, "runas", "python", f'"{script_path}"', None, 1
                    )
                    self.root.quit()
                except Exception as e:
                    messagebox.showerror("错误", f"无法以管理员权限启动程序: {str(e)}")
            return
        
        ip = self.printer_ip.get().strip()
        if not self.is_valid_ip(ip):
            messagebox.showerror("错误", "请输入有效的IP地址")
            return
        
        # 显示处理中对话框
        self.process_window = tk.Toplevel(self.root)
        self.process_window.title("处理中")
        self.process_window.geometry("300x100")
        self.process_window.resizable(False, False)
        self.process_window.transient(self.root)
        self.process_window.grab_set()
        
        label = ttk.Label(self.process_window, text="正在检查并删除现有打印机...")
        label.pack(pady=20)
        
        # 在新线程中执行检查和删除操作
        threading.Thread(target=self._check_and_remove_printer_thread, args=(ip,), daemon=True).start()
    
    def _check_and_remove_printer_thread(self, ip):
        try:
            # 获取所有打印机
            printers = win32print.EnumPrinters(win32print.PRINTER_ENUM_LOCAL | win32print.PRINTER_ENUM_CONNECTIONS)
            removed = False
            removed_printers = []
            failed_printers = []
            
            # 第一步：查找所有匹配的打印机
            matching_printers = []
            for printer_info in printers:
                printer_name = printer_info[2]
                # 获取打印机详情
                try:
                    printer_handle = win32print.OpenPrinter(printer_name)
                    printer_data = win32print.GetPrinter(printer_handle, 2)
                    win32print.ClosePrinter(printer_handle)
                    
                    # 检查端口是否包含IP地址
                    port_name = printer_data['pPortName']
                    if ip in port_name:
                        matching_printers.append((printer_name, port_name))
                except Exception as e:
                    print(f"获取打印机 {printer_name} 信息失败: {str(e)}")
                    pass
            
            # 如果没有找到匹配的打印机，直接返回
            if not matching_printers:
                self.root.after(0, self._show_check_result, False, [])
                return
            
            # 第二步：尝试多种方法删除每个匹配的打印机
            for printer_name, port_name in matching_printers:
                success = False
                
                # 方法1：使用win32print删除本地打印机
                try:
                    delete_handle = win32print.OpenPrinter(printer_name)
                    win32print.DeletePrinter(delete_handle)
                    win32print.ClosePrinter(delete_handle)
                    success = True
                    print(f"通过win32print成功删除打印机: {printer_name}")
                except Exception as e:
                    print(f"通过win32print删除打印机 {printer_name} 失败: {str(e)}")
                
                # 方法2：使用rundll32命令删除 - 增强特殊字符处理
                if not success:
                    try:
                        safe_printer_name = self._sanitize_printer_name(printer_name)
                        delete_cmd = f'rundll32 printui.dll,PrintUIEntry /dn /n"{safe_printer_name}"'
                        result = subprocess.run(delete_cmd, shell=True, capture_output=True, text=True)
                        if result.returncode == 0:
                            success = True
                            print(f"通过rundll32成功删除打印机: {printer_name}")
                        else:
                            print(f"通过rundll32删除打印机 {printer_name} 失败: {result.stderr}")
                    except Exception as e:
                        print(f"使用rundll32删除打印机 {printer_name} 异常: {str(e)}")
                
                # 方法3：使用PowerShell删除 - 增强特殊字符处理
                if not success:
                    try:
                        safe_printer_name = self._sanitize_printer_name(printer_name)
                        ps_cmd = f'powershell -Command "Remove-Printer -Name \\"{safe_printer_name}\\" -ErrorAction SilentlyContinue"'
                        result = subprocess.run(ps_cmd, shell=True, capture_output=True, text=True)
                        if result.returncode == 0 or "not found" not in result.stderr.lower():
                            success = True
                            print(f"通过PowerShell成功删除打印机: {printer_name}")
                        else:
                            print(f"通过PowerShell删除打印机 {printer_name} 失败: {result.stderr}")
                    except Exception as e:
                        print(f"使用PowerShell删除打印机 {printer_name} 异常: {str(e)}")
                
                # 方法4：使用WMI删除 - 增强特殊字符处理
                if not success:
                    try:
                        safe_printer_name = self._sanitize_printer_name(printer_name)
                        wmi_cmd = f'wmic printer where "Name=\'{safe_printer_name}\'" delete'
                        result = subprocess.run(wmi_cmd, shell=True, capture_output=True, text=True)
                        if result.returncode == 0:
                            success = True
                            print(f"通过WMI成功删除打印机: {printer_name}")
                        else:
                            print(f"通过WMI删除打印机 {printer_name} 失败: {result.stderr}")
                    except Exception as e:
                        print(f"使用WMI删除打印机 {printer_name} 异常: {str(e)}")
                
                # 方法5：使用regedit删除注册表项 - 增强特殊字符处理
                if not success:
                    try:
                        # 删除打印机注册表项
                        safe_printer_name = self._sanitize_printer_name(printer_name)
                        reg_cmd = f'reg delete "HKLM\\SYSTEM\\CurrentControlSet\\Control\\Print\\Printers\\{safe_printer_name}" /f'
                        result = subprocess.run(reg_cmd, shell=True, capture_output=True, text=True)
                        if result.returncode == 0:
                            print(f"通过注册表删除打印机 {printer_name} 成功")
                            success = True
                        else:
                            print(f"通过注册表删除打印机 {printer_name} 失败: {result.stderr}")
                    except Exception as e:
                        print(f"使用注册表删除打印机 {printer_name} 异常: {str(e)}")
                
                # 删除端口
                if success:
                    port_deleted = False
                    
                    # 确保端口名称格式一致
                    # 如果端口名称不是以"IP_"开头，则尝试转换为标准格式
                    standard_port_name = port_name
                    if not port_name.startswith("IP_") and ip in port_name:
                        standard_port_name = f"IP_{ip}"
                    
                    # 删除端口前，先删除所有使用该端口的打印机
                    try:
                        # 获取所有打印机列表
                        printers_cmd = 'cscript //nologo "C:\\Windows\\System32\\Printing_Admin_Scripts\\zh-CN\\prnmngr.vbs" -l'
                        printers_result = subprocess.run(printers_cmd, shell=True, capture_output=True, text=True)
                        
                        if printers_result.returncode == 0:
                            # 解析打印机列表，查找使用该端口的打印机
                            printers_to_delete = []
                            lines = printers_result.stdout.split('\n')
                            current_printer = None
                            
                            for line in lines:
                                line = line.strip()
                                if line.startswith("打印机名 "):
                                    current_printer = line.replace("打印机名 ", "").strip()
                                elif line.startswith("端口名 ") and current_printer:
                                    port_used = line.replace("端口名 ", "").strip()
                                    if port_used == port_name or port_used == standard_port_name:
                                        printers_to_delete.append(current_printer)
                                    current_printer = None
                            
                            # 删除使用该端口的打印机 - 增强特殊字符处理
                            for printer_name in printers_to_delete:
                                try:
                                    safe_printer_name = self._sanitize_printer_name(printer_name)
                                    delete_printer_cmd = f'cscript //nologo "C:\\Windows\\System32\\Printing_Admin_Scripts\\zh-CN\\prnmngr.vbs" -d -p "{safe_printer_name}"'
                                    delete_result = subprocess.run(delete_printer_cmd, shell=True, capture_output=True, text=True)
                                    if delete_result.returncode == 0:
                                        print(f"成功删除使用端口 {port_name} 的打印机: {printer_name}")
                                    else:
                                        print(f"删除打印机 {printer_name} 失败: {delete_result.stderr}")
                                except Exception as e:
                                    print(f"删除打印机 {printer_name} 异常: {str(e)}")
                    except Exception as e:
                        print(f"获取打印机列表异常: {str(e)}")
                    
                    # 方法1：使用prnport.vbs删除端口 - 增强特殊字符处理
                    try:
                        # 先尝试原始端口名
                        safe_port_name = self._sanitize_printer_name(port_name)
                        port_cmd = f'cscript //nologo "C:\\Windows\\System32\\Printing_Admin_Scripts\\zh-CN\\prnport.vbs" -d -r "{safe_port_name}"'
                        result = subprocess.run(port_cmd, shell=True, capture_output=True, text=True)
                        if result.returncode == 0:
                            port_deleted = True
                            print(f"通过prnport.vbs成功删除端口: {port_name}")
                        # 如果原始端口名失败，尝试标准格式端口名
                        elif port_name != standard_port_name:
                            safe_standard_port_name = self._sanitize_printer_name(standard_port_name)
                            port_cmd = f'cscript //nologo "C:\\Windows\\System32\\Printing_Admin_Scripts\\zh-CN\\prnport.vbs" -d -r "{safe_standard_port_name}"'
                            result = subprocess.run(port_cmd, shell=True, capture_output=True, text=True)
                            if result.returncode == 0:
                                port_deleted = True
                                print(f"通过prnport.vbs成功删除端口(标准格式): {standard_port_name}")
                            else:
                                print(f"通过prnport.vbs删除端口 {port_name}/{standard_port_name} 失败: {result.stderr}")
                        else:
                            print(f"通过prnport.vbs删除端口 {port_name} 失败: {result.stderr}")
                    except Exception as e:
                        print(f"使用prnport.vbs删除端口 {port_name} 异常: {str(e)}")
                    
                    # 方法2：使用PowerShell删除端口 - 增强特殊字符处理
                    if not port_deleted:
                        try:
                            # 先尝试原始端口名
                            safe_port_name = self._sanitize_printer_name(port_name)
                            ps_port_cmd = f'powershell -Command "Remove-PrinterPort -Name \\"{safe_port_name}\\" -ErrorAction SilentlyContinue"'
                            result = subprocess.run(ps_port_cmd, shell=True, capture_output=True, text=True)
                            if result.returncode == 0 or "not found" not in result.stderr.lower():
                                port_deleted = True
                                print(f"通过PowerShell成功删除端口: {port_name}")
                            # 如果原始端口名失败，尝试标准格式端口名
                            elif port_name != standard_port_name:
                                safe_standard_port_name = self._sanitize_printer_name(standard_port_name)
                                ps_port_cmd = f'powershell -Command "Remove-PrinterPort -Name \\"{safe_standard_port_name}\\" -ErrorAction SilentlyContinue"'
                                result = subprocess.run(ps_port_cmd, shell=True, capture_output=True, text=True)
                                if result.returncode == 0 or "not found" not in result.stderr.lower():
                                    port_deleted = True
                                    print(f"通过PowerShell成功删除端口(标准格式): {standard_port_name}")
                                else:
                                    print(f"通过PowerShell删除端口 {port_name}/{standard_port_name} 失败: {result.stderr}")
                            else:
                                print(f"通过PowerShell删除端口 {port_name} 失败: {result.stderr}")
                        except Exception as e:
                            print(f"使用PowerShell删除端口 {port_name} 异常: {str(e)}")
                    
                    # 方法3：使用注册表删除端口 - 增强特殊字符处理
                    if not port_deleted:
                        try:
                            # 先尝试原始端口名
                            safe_port_name = self._sanitize_printer_name(port_name)
                            port_reg_cmd = f'reg delete "HKLM\\SYSTEM\\CurrentControlSet\\Control\\Print\\Monitors\\Standard TCP/IP Port\\Ports\\{safe_port_name}" /f'
                            result = subprocess.run(port_reg_cmd, shell=True, capture_output=True, text=True)
                            if result.returncode == 0:
                                port_deleted = True
                                print(f"通过注册表成功删除端口: {port_name}")
                            # 如果原始端口名失败，尝试标准格式端口名
                            elif port_name != standard_port_name:
                                safe_standard_port_name = self._sanitize_printer_name(standard_port_name)
                                port_reg_cmd = f'reg delete "HKLM\\SYSTEM\\CurrentControlSet\\Control\\Print\\Monitors\\Standard TCP/IP Port\\Ports\\{safe_standard_port_name}" /f'
                                result = subprocess.run(port_reg_cmd, shell=True, capture_output=True, text=True)
                                if result.returncode == 0:
                                    port_deleted = True
                                    print(f"通过注册表成功删除端口(标准格式): {standard_port_name}")
                                else:
                                    print(f"通过注册表删除端口 {port_name}/{standard_port_name} 失败: {result.stderr}")
                            else:
                                print(f"通过注册表删除端口 {port_name} 失败: {result.stderr}")
                        except Exception as e:
                            print(f"使用注册表删除端口 {port_name} 异常: {str(e)}")
                    
                    # 方法4：使用WMI删除端口 - 增强特殊字符处理
                    if not port_deleted:
                        try:
                            # 先尝试原始端口名
                            safe_port_name = self._sanitize_printer_name(port_name)
                            wmi_port_cmd = f'wmic path win32_tcpipprinterport where "Name=\'{safe_port_name}\'" delete'
                            result = subprocess.run(wmi_port_cmd, shell=True, capture_output=True, text=True)
                            if result.returncode == 0:
                                port_deleted = True
                                print(f"通过WMI成功删除端口: {port_name}")
                            # 如果原始端口名失败，尝试标准格式端口名
                            elif port_name != standard_port_name:
                                safe_standard_port_name = self._sanitize_printer_name(standard_port_name)
                                wmi_port_cmd = f'wmic path win32_tcpipprinterport where "Name=\'{safe_standard_port_name}\'" delete'
                                result = subprocess.run(wmi_port_cmd, shell=True, capture_output=True, text=True)
                                if result.returncode == 0:
                                    port_deleted = True
                                    print(f"通过WMI成功删除端口(标准格式): {standard_port_name}")
                                else:
                                    print(f"通过WMI删除端口 {port_name}/{standard_port_name} 失败: {result.stderr}")
                            else:
                                print(f"通过WMI删除端口 {port_name} 失败: {result.stderr}")
                        except Exception as e:
                            print(f"使用WMI删除端口 {port_name} 异常: {str(e)}")
                    
                    # 如果所有方法都失败，记录详细错误信息
                    if not port_deleted:
                        print(f"警告: 所有方法都无法删除端口 {port_name}，这可能导致后续安装失败")
                        print(f"请手动检查并删除端口 {port_name} 和 {standard_port_name}")
            
            # 刷新打印机缓存
            try:
                print("尝试刷新打印机缓存...")
                simple_restart = 'net stop spooler && net start spooler'
                result = subprocess.run(simple_restart, shell=True, capture_output=True, text=True)
                if result.returncode == 0:
                    print("打印服务重启成功")
                    import time
                    time.sleep(3)
                    print("打印机缓存刷新完成")
                else:
                    print(f"重启打印服务失败: {result.stderr}")
            except Exception as e:
                print(f"重启打印服务异常: {str(e)}")
                
        except Exception as e:
            print(f"自动删除打印机时出错: {str(e)}")
    
    def _sanitize_printer_name(self, printer_name):
        """清理打印机名称，处理特殊字符"""
        # 替换可能导致命令行解析问题的字符
        # 1. 替换双引号为转义的双引号
        safe_name = printer_name.replace('"', '""')
        
        # 2. 如果名称中包含百分号，可能会被命令行解释器误解
        safe_name = safe_name.replace('%', '%%')
        
        # 3. 如果名称以连字符开头，可能会被误认为是命令选项
        if safe_name.startswith('-'):
            safe_name = '\\' + safe_name
            
        return safe_name

    def _auto_remove_printers_for_ip(self, ip):
        """自动删除指定IP的现有打印机"""
        try:
            print(f"正在检查并删除IP为 {ip} 的现有打印机...")
            
            # 获取所有打印机
            printers = win32print.EnumPrinters(win32print.PRINTER_ENUM_LOCAL | win32print.PRINTER_ENUM_CONNECTIONS)
            removed_count = 0
            
            # 查找匹配的打印机
            for printer_info in printers:
                printer_name = printer_info[2]
                try:
                    printer_handle = win32print.OpenPrinter(printer_name)
                    printer_data = win32print.GetPrinter(printer_handle, 2)
                    win32print.ClosePrinter(printer_handle)
                    
                    # 检查端口是否包含IP地址
                    port_name = printer_data['pPortName']
                    if ip in port_name:
                        print(f"找到匹配的打印机: {printer_name} (端口: {port_name})")
                        
                        # 尝试删除打印机
                        success = False
                        
                        # 方法1：使用win32print删除
                        try:
                            delete_handle = win32print.OpenPrinter(printer_name)
                            win32print.DeletePrinter(delete_handle)
                            win32print.ClosePrinter(delete_handle)
                            success = True
                            print(f"通过win32print成功删除打印机: {printer_name}")
                        except Exception as e:
                            print(f"通过win32print删除打印机 {printer_name} 失败: {str(e)}")
                        
                        # 方法2：使用rundll32删除 - 增强特殊字符处理
                        if not success:
                            try:
                                # 更安全的打印机名称处理
                                safe_printer_name = self._sanitize_printer_name(printer_name)
                                delete_cmd = f'rundll32 printui.dll,PrintUIEntry /dn /n"{safe_printer_name}"'
                                result = subprocess.run(delete_cmd, shell=True, capture_output=True, text=True)
                                if result.returncode == 0:
                                    success = True
                                    print(f"通过rundll32成功删除打印机: {printer_name}")
                                else:
                                    print(f"通过rundll32删除打印机 {printer_name} 失败: {result.stderr}")
                            except Exception as e:
                                print(f"使用rundll32删除打印机 {printer_name} 异常: {str(e)}")
                        
                        # 方法3：使用PowerShell删除 - 增强特殊字符处理
                        if not success:
                            try:
                                # 使用更安全的方式处理打印机名称
                                safe_printer_name = self._sanitize_printer_name(printer_name)
                                ps_cmd = f'powershell -Command "Remove-Printer -Name \\"{safe_printer_name}\\" -ErrorAction SilentlyContinue"'
                                result = subprocess.run(ps_cmd, shell=True, capture_output=True, text=True)
                                if result.returncode == 0 or "not found" not in result.stderr.lower():
                                    success = True
                                    print(f"通过PowerShell成功删除打印机: {printer_name}")
                                else:
                                    print(f"通过PowerShell删除打印机 {printer_name} 失败: {result.stderr}")
                            except Exception as e:
                                print(f"使用PowerShell删除打印机 {printer_name} 异常: {str(e)}")
                        
                        # 方法4：使用WMI删除 - 增强特殊字符处理
                        if not success:
                            try:
                                # 使用更安全的方式处理打印机名称
                                safe_printer_name = self._sanitize_printer_name(printer_name)
                                wmi_cmd = f'wmic printer where "Name=\'{safe_printer_name}\'" delete'
                                result = subprocess.run(wmi_cmd, shell=True, capture_output=True, text=True)
                                if result.returncode == 0:
                                    success = True
                                    print(f"通过WMI成功删除打印机: {printer_name}")
                                else:
                                    print(f"通过WMI删除打印机 {printer_name} 失败: {result.stderr}")
                            except Exception as e:
                                print(f"使用WMI删除打印机 {printer_name} 异常: {str(e)}")
                        
                        if success:
                            removed_count += 1
                            
                except Exception as e:
                    print(f"获取打印机 {printer_name} 信息失败: {str(e)}")
                    continue
            
            if removed_count > 0:
                print(f"成功删除了 {removed_count} 个IP为 {ip} 的打印机")
            else:
                print(f"没有找到IP为 {ip} 的现有打印机")
                
        except Exception as e:
            print(f"自动删除打印机时发生错误: {str(e)}")
    
    def _show_driver_selection_dialog(self, driver_names, ip, name, inf_path):
        """显示驱动选择对话框"""
        # 创建选择对话框
        dialog = tk.Toplevel(self.root)
        dialog.title("选择驱动")
        dialog.geometry("500x400")
        dialog.resizable(True, True)
        dialog.transient(self.root)
        dialog.grab_set()
        
        # 添加说明标签
        label = ttk.Label(dialog, text="从INF文件中检测到以下驱动，请选择要安装的驱动：")
        label.pack(pady=10, padx=10, anchor='w')
        
        # 创建框架用于显示驱动列表
        frame = ttk.Frame(dialog)
        frame.pack(fill=tk.BOTH, expand=True, padx=10, pady=5)
        
        # 创建滚动条
        scrollbar = ttk.Scrollbar(frame)
        scrollbar.pack(side=tk.RIGHT, fill=tk.Y)
        
        # 创建列表框
        listbox = tk.Listbox(frame, yscrollcommand=scrollbar.set, font=('Arial', 10))
        listbox.pack(side=tk.LEFT, fill=tk.BOTH, expand=True)
        scrollbar.config(command=listbox.yview)
        
        # 添加驱动名称到列表框
        for driver_name in driver_names:
            listbox.insert(tk.END, driver_name)
        
        # 默认选择第一个
        if driver_names:
            listbox.selection_set(0)
        
        # 添加按钮框架
        button_frame = ttk.Frame(dialog)
        button_frame.pack(fill=tk.X, padx=10, pady=10)
        
        # 添加自定义驱动输入框
        custom_frame = ttk.Frame(dialog)
        custom_frame.pack(fill=tk.X, padx=10, pady=5)
        
        custom_label = ttk.Label(custom_frame, text="或输入自定义驱动名称:")
        custom_label.pack(anchor='w')
        
        custom_entry = ttk.Entry(custom_frame, font=('Arial', 10))
        custom_entry.pack(fill=tk.X, pady=5)
        
        # 存储选择的驱动名称
        selected_driver = tk.StringVar()
        
        def on_select():
            selection = listbox.curselection()
            if selection:
                selected_driver.set(driver_names[selection[0]])
                custom_entry.delete(0, tk.END)
                custom_entry.insert(0, selected_driver.get())
        
        def on_custom_entry_change(event=None):
            selected_driver.set(custom_entry.get())
        
        listbox.bind('<<ListboxSelect>>', lambda e: on_select())
        custom_entry.bind('<KeyRelease>', on_custom_entry_change)
        
        # 初始化选择
        on_select()
        
        # 添加按钮
        def on_install():
            driver_name = selected_driver.get().strip()
            if not driver_name:
                messagebox.showerror("错误", "请选择或输入驱动名称")
                return
            
            # 关闭对话框
            dialog.destroy()
            
            # 显示安装进度对话框
            self.process_window = tk.Toplevel(self.root)
            self.process_window.title("安装中")
            self.process_window.geometry("300x100")
            self.process_window.resizable(False, False)
            self.process_window.transient(self.root)
            self.process_window.grab_set()
            
            label = ttk.Label(self.process_window, text="正在安装打印机，请稍候...")
            label.pack(pady=20)
            
            # 在新线程中执行安装
            threading.Thread(
                target=self._install_printer_with_selected_driver, 
                args=(ip, name, inf_path, driver_name), 
                daemon=True
            ).start()
        
        def on_cancel():
            dialog.destroy()
        
        install_button = ttk.Button(button_frame, text="安装", command=on_install)
        install_button.pack(side=tk.RIGHT, padx=5)
        
        cancel_button = ttk.Button(button_frame, text="取消", command=on_cancel)
        cancel_button.pack(side=tk.RIGHT)
        
        # 居中显示对话框
        dialog.update_idletasks()
        width = dialog.winfo_width()
        height = dialog.winfo_height()
        x = (dialog.winfo_screenwidth() // 2) - (width // 2)
        y = (dialog.winfo_screenheight() // 2) - (height // 2)
        dialog.geometry(f'{width}x{height}+{x}+{y}')
        
        return dialog
    
    def install_printer(self):
        # 获取用户输入
        ip = self.printer_ip.get().strip()
        name = self.printer_name.get().strip()
        driver_path = self.driver_path.get().strip()
        inf_file = self.selected_inf.get()
        
        # 完整的INF文件路径
        full_inf_path = os.path.join(driver_path, inf_file)
        
        # 在安装新打印机之前，先删除与该IP相关的旧打印机
        self._auto_remove_printers_for_ip(ip)
        
        # 从INF文件中提取驱动名称
        driver_names = self._get_driver_names_from_inf(full_inf_path)
        
        # 如果没有找到驱动名称，使用默认的驱动名称列表
        if not driver_names:
            inf_filename = os.path.basename(full_inf_path).lower()
            if 'hphu0f814' in inf_filename:
                driver_names = [
                    "HP LaserJet Pro MFP 3101-3108 PCL-6 (V4)",
                    "HP LaserJet Pro MFP M3104",
                    "HP LaserJet Pro MFP M310",
                    "HP LaserJet Pro M3104",
                    "HP LaserJet M3104",
                    "HP Universal Printing PCL 6",
                    "HP Universal Printing PCL5",
                    "HP LaserJet Pro MFP",
                    "HP LaserJet"
                ]
            else:
                # 使用文件名作为默认驱动名称
                driver_names = [os.path.splitext(os.path.basename(full_inf_path))[0]]
        
        # 显示驱动选择对话框
        self._show_driver_selection_dialog(driver_names, ip, name, full_inf_path)
    
    def _install_printer_with_selected_driver(self, ip, name, inf_path, selected_driver_name):
        """使用用户选择的驱动名称安装打印机"""
        # 创建一个日志文件记录安装过程
        log_file_path = os.path.join(os.path.dirname(os.path.abspath(__file__)), 'install_log.txt')
        
        def log(message):
            with open(log_file_path, 'a', encoding='utf-8') as f:
                f.write(f"[{datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S')}] {message}\n")
        
        # 清空旧日志
        with open(log_file_path, 'w', encoding='utf-8') as f:
            f.write(f"开始安装打印机: {name}, IP: {ip}, 驱动: {inf_path}, 选择的驱动: {selected_driver_name}\n")
        
        try:
            log("检查管理员权限...")
            # 增强权限检查
            if not ctypes.windll.shell32.IsUserAnAdmin():
                error_msg = "当前进程没有足够的管理员权限，请以管理员身份重新运行程序"
                log(f"错误: {error_msg}")
                self.root.after(0, self._show_install_result, False, error_msg)
                return
            log("管理员权限检查通过")
            
            # 获取Windows系统目录
            win_dir = os.environ.get('WINDIR', 'C:\\Windows')
            script_dir = os.path.join(win_dir, 'System32', 'Printing_Admin_Scripts', 'zh-CN')
            log(f"Windows目录: {win_dir}, 脚本目录: {script_dir}")
            
            # 验证脚本目录是否存在
            if not os.path.exists(script_dir):
                # 尝试使用英文目录
                script_dir = os.path.join(win_dir, 'System32', 'Printing_Admin_Scripts', 'en-US')
                log(f"尝试英文脚本目录: {script_dir}")
                if not os.path.exists(script_dir):
                    error_msg = f"找不到打印管理脚本目录: {script_dir}"
                    log(f"错误: {error_msg}")
                    self.root.after(0, self._show_install_result, False, error_msg)
                    return
            log(f"使用脚本目录: {script_dir}")
            
            # 创建IPP端口
            port_name = f"IP_{ip}"
            log(f"准备创建/检查端口: {port_name}")
            
            # 检查端口是否已存在，如果不存在则创建
            prnport_vbs = os.path.join(script_dir, 'prnport.vbs')
            log(f"prnport.vbs路径: {prnport_vbs}")
            
            if not os.path.exists(prnport_vbs):
                error_msg = f"找不到prnport.vbs脚本: {prnport_vbs}"
                log(f"错误: {error_msg}")
                self.root.after(0, self._show_install_result, False, error_msg)
                return
            
            cmd_check_port = f'cscript //nologo "{prnport_vbs}" -l | findstr "{port_name}"'
            log(f"执行命令: {cmd_check_port}")
            result = subprocess.run(cmd_check_port, shell=True, capture_output=True, text=True)
            log(f"端口检查返回代码: {result.returncode}, 输出: {result.stdout}")
            
            if port_name not in result.stdout:
                # 创建IPP端口
                cmd_create_port = f'cscript //nologo "{prnport_vbs}" -a -r "{port_name}" -h {ip} -o ipp -n 631'
                log(f"执行命令: {cmd_create_port}")
                result = subprocess.run(cmd_create_port, shell=True, capture_output=True, text=True)
                log(f"端口创建返回代码: {result.returncode}, 输出: {result.stdout}, 错误: {result.stderr}")
                
                if result.returncode != 0:
                    error_msg = f"创建端口失败: {result.stderr or result.stdout}"
                    log(f"错误: {error_msg}")
                    self.root.after(0, self._show_install_result, False, error_msg)
                    return
                log("端口创建成功")
            else:
                log("端口已存在，跳过创建")
            
            # 安装驱动
            log(f"开始安装驱动: {inf_path}")
            cmd_add_driver = f'pnputil /add-driver "{inf_path}" /install'
            log(f"执行命令: {cmd_add_driver}")
            result = subprocess.run(cmd_add_driver, shell=True, capture_output=True, text=True)
            log(f"驱动安装返回代码: {result.returncode}, 输出: {result.stdout}, 错误: {result.stderr}")
            
            if result.returncode != 0:
                error_msg = f"安装驱动失败: {result.stderr or result.stdout}"
                log(f"错误: {error_msg}")
                self.root.after(0, self._show_install_result, False, error_msg)
                return
            log("驱动安装成功")
            
            # 添加打印机，使用用户选择的驱动名称
            prnmngr_vbs = os.path.join(script_dir, 'prnmngr.vbs')
            log(f"prnmngr.vbs路径: {prnmngr_vbs}")
            
            if not os.path.exists(prnmngr_vbs):
                error_msg = f"找不到prnmngr.vbs脚本: {prnmngr_vbs}"
                log(f"错误: {error_msg}")
                self.root.after(0, self._show_install_result, False, error_msg)
                return
            
            # 使用用户选择的驱动名称
            driver_name = selected_driver_name
            log(f"使用用户选择的驱动名称: {driver_name}")
            
            cmd_add_printer = f'cscript //nologo "{prnmngr_vbs}" -a -p "{name}" -m "{driver_name}" -r "{port_name}"'  
            log(f"执行命令: {cmd_add_printer}")
            result = subprocess.run(cmd_add_printer, shell=True, capture_output=True, text=True)
            log(f"添加打印机返回代码: {result.returncode}, 输出: {result.stdout}, 错误: {result.stderr}")
            
            # 如果失败，尝试使用系统中已安装的HP驱动
            if result.returncode != 0:
                log("使用选择的驱动失败，尝试系统中已安装的HP驱动")
                
                # 获取系统中已安装的HP驱动列表
                try:
                    cmd_get_drivers = 'powershell -Command "Get-PrinterDriver | Where-Object {$_.Name -like \'*HP*\'} | Select-Object Name"'
                    log(f"执行命令: {cmd_get_drivers}")
                    drivers_result = subprocess.run(cmd_get_drivers, shell=True, capture_output=True, text=True, timeout=10)
                    log(f"HP驱动列表返回代码: {drivers_result.returncode}, 输出: {drivers_result.stdout}")
                    
                    # 解析驱动列表
                    available_hp_drivers = []
                    if drivers_result.returncode == 0:
                        for line in drivers_result.stdout.split('\n'):
                            if line.strip() and not line.startswith('---') and not line.startswith('Name'):
                                driver = line.strip()
                                if driver and driver != 'Name':
                                    available_hp_drivers.append(driver)
                    
                    log(f"系统中的HP驱动列表: {available_hp_drivers}")
                except Exception as e:
                    log(f"获取HP驱动列表错误: {str(e)}")
                    available_hp_drivers = []
                
                # 优先尝试系统中已安装的HP驱动
                success = False
                for available_driver in available_hp_drivers:
                    if available_driver != driver_name:  # 跳过已经尝试过的驱动
                        log(f"尝试已安装的HP驱动: {available_driver}")
                        cmd_add_printer = f'cscript //nologo "{prnmngr_vbs}" -a -p "{name}" -m "{available_driver}" -r "{port_name}"'
                        log(f"执行命令: {cmd_add_printer}")
                        result = subprocess.run(cmd_add_printer, shell=True, capture_output=True, text=True)
                        log(f"返回代码: {result.returncode}, 输出: {result.stdout}, 错误: {result.stderr}")
                        
                        if result.returncode == 0:
                            driver_name = available_driver
                            success = True
                            log(f"使用驱动 {available_driver} 成功添加打印机")
                            break
                
                # 如果使用已安装驱动仍然失败，尝试通用驱动名
                if not success:
                    log("尝试通用驱动名")
                    common_driver_names = [
                        "HP Universal Printing PCL 6",
                        "HP Universal Printing PCL5",
                        "HP LaserJet Pro MFP M3104",
                        "HP LaserJet Pro MFP M310",
                        "HP LaserJet Pro",
                        "HP LaserJet"
                    ]
                    
                    for common_driver in common_driver_names:
                        if common_driver != driver_name and common_driver not in available_hp_drivers:  # 避免重复尝试
                            log(f"尝试通用驱动: {common_driver}")
                            cmd_add_printer = f'cscript //nologo "{prnmngr_vbs}" -a -p "{name}" -m "{common_driver}" -r "{port_name}"'
                            log(f"执行命令: {cmd_add_printer}")
                            result = subprocess.run(cmd_add_printer, shell=True, capture_output=True, text=True)
                            log(f"返回代码: {result.returncode}, 输出: {result.stdout}, 错误: {result.stderr}")
                            
                            if result.returncode == 0:
                                driver_name = common_driver
                                success = True
                                log(f"使用驱动 {common_driver} 成功添加打印机")
                                break
                
                if not success:
                    error_msg = f"添加打印机失败，已尝试多种驱动: {result.stderr or result.stdout}"
                    log(f"错误: {error_msg}")
                    self.root.after(0, self._show_install_result, False, error_msg)
                    return
            log("打印机添加成功")
            
            # 设置为默认打印机
            cmd_set_default = f'cscript //nologo "{prnmngr_vbs}" -t -p "{name}"'
            log(f"执行命令: {cmd_set_default}")
            result = subprocess.run(cmd_set_default, shell=True, capture_output=True, text=True)
            log(f"设置默认打印机返回代码: {result.returncode}, 输出: {result.stdout}")
            
            # 更严格的验证逻辑
            log("开始验证打印机安装...")
            printer_found = False
            verification_attempts = 0
            max_attempts = 5  # 增加尝试次数
            
            while not printer_found and verification_attempts < max_attempts:
                verification_attempts += 1
                log(f"验证尝试 {verification_attempts}/{max_attempts}")
                
                # 尝试方法1: 使用PowerShell Get-Printer
                try:
                    cmd_verify_printer = f'powershell -Command "Get-Printer -Name \\"{name}\\" | Format-List *"'
                    log(f"执行命令: {cmd_verify_printer}")
                    verify_result = subprocess.run(cmd_verify_printer, shell=True, capture_output=True, text=True, timeout=10)
                    log(f"PowerShell验证返回代码: {verify_result.returncode}, 输出: {verify_result.stdout}")
                    if verify_result.returncode == 0 and name in verify_result.stdout:
                        printer_found = True
                        log("PowerShell验证成功")
                        break
                except Exception as e:
                    log(f"PowerShell验证错误: {str(e)}")
                
                # 尝试方法2: 使用prnmngr.vbs -l
                try:
                    cmd_alt_verify = f'cscript //nologo "{prnmngr_vbs}" -l'
                    log(f"执行命令: {cmd_alt_verify}")
                    alt_result = subprocess.run(cmd_alt_verify, shell=True, capture_output=True, text=True, timeout=10)
                    log(f"VBS验证返回代码: {alt_result.returncode}, 输出: {alt_result.stdout}")
                    if name.lower() in alt_result.stdout.lower():
                        printer_found = True
                        log("VBS验证成功")
                        break
                except Exception as e:
                    log(f"VBS验证错误: {str(e)}")
                
                # 尝试方法3: 使用win32print API
                try:
                    log("使用win32print API验证")
                    printers = [printer[2] for printer in win32print.EnumPrinters(win32print.PRINTER_ENUM_LOCAL | win32print.PRINTER_ENUM_CONNECTIONS)]
                    log(f"系统打印机列表: {printers}")
                    if any(name.lower() in printer_name.lower() for printer_name in printers):
                        printer_found = True
                        log("win32print API验证成功")
                        break
                except Exception as e:
                    log(f"win32print API验证错误: {str(e)}")
                
                # 尝试方法4: 使用Windows命令行dir命令检查打印机文件夹
                try:
                    cmd_dir_print = 'dir "C:\\Windows\\System32\\spool\\printers" /b'
                    log(f"执行命令: {cmd_dir_print}")
                    dir_result = subprocess.run(cmd_dir_print, shell=True, capture_output=True, text=True, timeout=5)
                    log(f"打印机文件夹检查: {dir_result.stdout}")
                except Exception as e:
                    log(f"打印机文件夹检查错误: {str(e)}")
                
                # 如果还没找到，等待一段时间再试
                if not printer_found and verification_attempts < max_attempts:
                    import time
                    log(f"等待2秒后再次验证...")
                    time.sleep(2)
            
            # 更新UI - 使用更准确的验证结果
            if printer_found:
                log("打印机验证成功，安装完成")
                self.root.after(0, self._show_install_result, True, "")
            else:
                # 严格模式：验证失败就报错，而不是提示可能成功
                error_msg = f"打印机安装命令已执行，但在系统中找不到打印机 '{name}'。请检查:\\n1. 是否有足够的管理员权限\\n2. 驱动是否兼容当前系统\\n3. 网络连接是否正常\\n4. 打印机服务是否正常运行"
                log(f"错误: {error_msg}")
                self.root.after(0, self._show_install_result, False, error_msg)
        except Exception as e:
            import traceback
            error_detail = traceback.format_exc()
            log(f"安装过程异常: {str(e)}")
            log(f"详细堆栈: {error_detail}")
            self.root.after(0, self._show_install_result, False, f"安装过程出现错误: {str(e)}\\n\\n详细错误:\\n{error_detail}")
    
    def _get_driver_names_from_inf(self, inf_path):
        """从INF文件中提取所有可能的驱动名称"""
        driver_names = set()
        try:
            with open(inf_path, 'r', encoding='utf-8', errors='ignore') as f:
                content = f.read()
                
            # 方法1: 查找[Strings]部分中的PRINTER变量
            strings_matches = re.findall(r'^\s*PRINTER\d+\s*=\s*"([^"]+)"', content, re.MULTILINE)
            for match in strings_matches:
                driver_names.add(match)
                
            # 方法2: 查找[Strings]部分中的任何变量
            strings_section = re.search(r'\[Strings\](.*?)(?=\[|\Z)', content, re.DOTALL | re.IGNORECASE)
            if strings_section:
                strings_content = strings_section.group(1)
                string_matches = re.findall(r'^\s*[A-Z0-9_]+\s*=\s*"([^"]+)"', strings_content, re.MULTILINE)
                for match in string_matches:
                    driver_names.add(match)
                    
            # 方法3: 查找[Strings.xx]部分中的任何变量
            strings_locale_matches = re.findall(r'\[Strings\.[0-9]+\](.*?)(?=\[|\Z)', content, re.DOTALL | re.IGNORECASE)
            for strings_content in strings_locale_matches:
                string_matches = re.findall(r'^\s*[A-Z0-9_]+\s*=\s*"([^"]+)"', strings_content, re.MULTILINE)
                for match in string_matches:
                    driver_names.add(match)
                    
            # 方法4: 查找DriverName字段
            driver_name_matches = re.findall(r'^\s*DriverName\s*=\s*"([^"]+)"', content, re.MULTILINE)
            for match in driver_name_matches:
                driver_names.add(match)
                
            # 方法5: 查找DeviceName字段
            device_name_matches = re.findall(r'^\s*DeviceName\s*=\s*"([^"]+)"', content, re.MULTILINE)
            for match in device_name_matches:
                driver_names.add(match)
                
            # 方法6: 查找Manufacturer节中的模型
            manufacturer_section = re.search(r'\[Manufacturer\](.*?)(?=\[|\Z)', content, re.DOTALL | re.IGNORECASE)
            if manufacturer_section:
                manufacturer_content = manufacturer_section.group(1)
                model_matches = re.findall(r'^"([^"]+)"', manufacturer_content, re.MULTILINE)
                for match in model_matches:
                    driver_names.add(match)
                    
            # 方法7: 查找Models节中的模型
            models_section = re.search(r'\[.*?Models\](.*?)(?=\[|\Z)', content, re.DOTALL | re.IGNORECASE)
            if models_section:
                models_content = models_section.group(1)
                model_matches = re.findall(r'^"([^"]+)"', models_content, re.MULTILINE)
                for match in model_matches:
                    driver_names.add(match)
                    
            # 方法8: 查找Printer节中的名称
            printer_section = re.search(r'\[.*?Printer\](.*?)(?=\[|\Z)', content, re.DOTALL | re.IGNORECASE)
            if printer_section:
                printer_content = printer_section.group(1)
                name_matches = re.findall(r'^\s*Name\s*=\s*"([^"]+)"', printer_content, re.MULTILINE)
                for match in name_matches:
                    driver_names.add(match)
                    
            return list(driver_names)
        except Exception as e:
            print(f"解析INF文件时出错: {e}")
            return []
    
    def _show_check_result(self, removed, removed_printers, failed_printers=None):
        if failed_printers is None:
            failed_printers = []
            
        self.process_window.destroy()
        
        if removed:
            message = f"已成功删除 {len(removed_printers)} 台打印机！"
            if failed_printers:
                message += f"\n\n但以下 {len(failed_printers)} 台打印机删除失败：\n" + "\n".join(failed_printers)
            
            result = messagebox.askyesno("删除结果", f"{message}\n\n是否查看详细信息？")
            if result:
                self._show_detailed_log(removed_printers, failed_printers)
        else:
            if failed_printers:
                message = f"删除失败！无法删除以下 {len(failed_printers)} 台打印机：\n" + "\n".join(failed_printers)
                messagebox.showerror("删除失败", f"{message}\n\n请尝试以管理员权限运行程序。")
            else:
                messagebox.showinfo("检查结果", "未找到匹配的打印机。")
    
    def _show_detailed_log(self, removed_printers, failed_printers):
        """显示删除打印机的详细日志"""
        # 显示详细信息窗口
        detail_window = tk.Toplevel(self.root)
        detail_window.title("删除打印机详细信息")
        detail_window.geometry("500x300")
        detail_window.resizable(True, True)
        detail_window.transient(self.root)
        
        # 添加文本框和滚动条
        text_frame = ttk.Frame(detail_window)
        text_frame.pack(fill=tk.BOTH, expand=True, padx=10, pady=10)
        
        text_widget = tk.Text(text_frame, wrap=tk.WORD)
        scrollbar = ttk.Scrollbar(text_frame, orient=tk.VERTICAL, command=text_widget.yview)
        text_widget.configure(yscrollcommand=scrollbar.set)
        
        text_widget.pack(side=tk.LEFT, fill=tk.BOTH, expand=True)
        scrollbar.pack(side=tk.RIGHT, fill=tk.Y)
        
        # 添加详细信息
        text_widget.insert(tk.END, "删除打印机操作日志:\n\n")
        
        if removed_printers:
            text_widget.insert(tk.END, "成功删除的打印机:\n")
            for printer in removed_printers:
                text_widget.insert(tk.END, f"✓ {printer}\n")
            text_widget.insert(tk.END, "\n")
        
        if failed_printers:
            text_widget.insert(tk.END, "删除失败的打印机:\n")
            for printer in failed_printers:
                text_widget.insert(tk.END, f"✗ {printer}\n")
            text_widget.insert(tk.END, "\n")
            text_widget.insert(tk.END, "提示: 删除失败可能是由于权限不足或打印机正在使用中。\n")
            text_widget.insert(tk.END, "建议: 以管理员权限运行程序或关闭正在使用打印机的应用程序。\n")
        
        text_widget.config(state=tk.DISABLED)
        
        # 添加关闭按钮
        close_button = ttk.Button(detail_window, text="关闭", command=detail_window.destroy)
        close_button.pack(pady=10)
    
    def _show_check_error(self, error_msg):
        self.process_window.destroy()
        messagebox.showerror("错误", f"检查打印机时出错: {error_msg}")
    
    def browse_driver_path(self):
        path = filedialog.askdirectory(title="选择驱动文件夹")
        if path:
            self.driver_path.set(path)
    
    def load_inf_files(self):
        path = self.driver_path.get().strip()
        self.inf_files = []
        
        try:
            # 查找所有INF文件
            for root, _, files in os.walk(path):
                for file in files:
                    if file.lower().endswith('.inf'):
                        # 添加相对路径
                        rel_path = os.path.relpath(os.path.join(root, file), path)
                        self.inf_files.append(rel_path)
            
            # 如果没有找到，尝试直接列出目录中的文件
            if not self.inf_files:
                try:
                    files = os.listdir(path)
                    for file in files:
                        if file.lower().endswith('.inf'):
                            self.inf_files.append(file)
                except:
                    pass
        except Exception as e:
            print(f"加载INF文件时出错: {e}")
    
    def on_inf_select(self, event):
        selection = self.inf_listbox.curselection()
        if selection:
            self.selected_inf.set(self.inf_files[selection[0]])
    
    def _show_install_result(self, success, error_msg):
        self.process_window.destroy()
        if success:
            messagebox.showinfo("成功", "打印机安装成功！")
            # 询问是否退出
            if messagebox.askyesno("完成", "安装已完成，是否退出程序？"):
                self.root.destroy()
            else:
                # 重置到第一步
                self.current_step = 1
                self.show_step(self.current_step)
                self.update_buttons()
        else:
            messagebox.showerror("安装失败", f"打印机安装失败: {error_msg}\n\n请尝试以管理员身份运行程序。")

def is_admin():
    """检查当前进程是否以管理员权限运行"""
    try:
        # 更可靠的管理员权限检查
        return ctypes.windll.shell32.IsUserAnAdmin() != 0
    except Exception as e:
        print(f"权限检查错误: {e}")
        return False

def run_as_admin():
    """以管理员权限重启当前程序"""
    try:
        script = os.path.abspath(sys.argv[0])
        params = ' '.join([script] + sys.argv[1:])
        
        # 使用更可靠的ShellExecuteEx调用方式
        result = shell.ShellExecuteEx(
            lpVerb='runas',
            lpFile=sys.executable,
            lpParameters=params,
            nShow=1
        )
        
        # 检查是否成功启动了新进程
        if result['hInstApp'] > 32:
            sys.exit(0)
        else:
            messagebox.showerror("提权失败", "无法以管理员身份重启程序。请手动右键点击程序并选择'以管理员身份运行'。")
            sys.exit(1)
    except Exception as e:
        messagebox.showerror("错误", f"提权过程出错: {str(e)}")
        sys.exit(1)

def main():
    # 检查是否以管理员权限运行
    if not is_admin():
        # 显示更详细的权限提示
        result = messagebox.askyesno(
            "需要管理员权限", 
            "安装打印机需要管理员权限才能创建端口、安装驱动和添加打印机。\n\n是否以管理员身份重启程序？"
        )
        if result:
            run_as_admin()
        else:
            messagebox.showinfo("提示", "程序将以普通模式运行，可能无法完成打印机安装。")
            # 不退出程序，允许用户尝试，但可能会在后续步骤中遇到权限错误
    
    root = tk.Tk()
    app = PrinterInstaller(root)
    
    # 添加窗口关闭事件处理
    def on_closing():
        if messagebox.askokcancel("退出", "确定要退出安装向导吗？"):
            root.destroy()
    
    root.protocol("WM_DELETE_WINDOW", on_closing)
    root.mainloop()

if __name__ == "__main__":
    main()